home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / obrn-a_1.5_src.lha / oberon-a / source3.lha / Source / ORU / ORU.mod next >
Encoding:
Text File  |  1995-01-26  |  21.0 KB  |  738 lines

  1. (*************************************************************************
  2.  
  3.      $RCSfile: ORU.mod $
  4.   Description: Generates a script file that will recompile modules
  5.                dependant on a given module.
  6.  
  7.    Created by: fjc (Frank Copeland)
  8.     $Revision: 2.8 $
  9.       $Author: fjc $
  10.         $Date: 1995/01/26 02:13:59 $
  11.  
  12.   Copyright © 1993-1995, Frank Copeland
  13.   This module forms part of the ORU program
  14.   See ORU.doc for conditions of use and distribution
  15.  
  16.   Log entries are at the end of the file.
  17.  
  18. *************************************************************************)
  19.  
  20. <* STANDARD- *>
  21.  
  22. MODULE ORU;
  23.  
  24. IMPORT
  25.   SYS := SYSTEM, ORURev, Errors, E := Exec, D := Dos, IU := IntuiUtil,
  26.   Args, Out, Str := Strings, L := Lists, Files;
  27.  
  28. CONST
  29.   CopyrightStr = "Copyright © 1993-1995 Frank Copeland\n";
  30.   UsageStr = "See ORU.doc for conditions of use\n";
  31.  
  32. CONST
  33.   MaxPaths         = 32;        (* Maximum number of search paths. *)
  34.   SymPattern       = "#?.sym";  (* Pattern to search for symbol files. *)
  35.   DefaultExtension = ".mod";    (* Default extension for source files. *)
  36.   DefaultPath      = "OLIB:";   (* Default path for symbols *)
  37.  
  38.   SymFileTag       = 53594D08H; (* "SYM" + version # *)
  39.   eMod = 26;                    (* Symbol file internal tags *)
  40.  
  41.   (* Error messages *)
  42.   OutOfMem  = " !! Out of memory\n";
  43.   OpenError = "\x9B\x4B !! Could not open ";
  44.  
  45. VAR
  46.   NotCD       : BOOLEAN;  (* Don't search current directory if TRUE. *)
  47.   All         : BOOLEAN;  (* Process all modules in search directories. *)
  48.   Symbols     : ARRAY MaxPaths + 1 OF E.LSTRPTR;
  49.                           (* Search paths for symbol files. *)
  50.   NumSymbols  : INTEGER;  (* Number of paths specified. *)
  51.   Source      : ARRAY MaxPaths + 1 OF E.LSTRPTR;
  52.                           (* Search paths for source files. *)
  53.   NumSources  : INTEGER;  (* Number of paths specified. *)
  54.   Destination : E.LSTRPTR; (* Destination directory for batch file. *)
  55.   Extension   : E.LSTRPTR; (* File extension for source files. *)
  56.   Module      : E.LSTRPTR; (* Name of redefined module. *)
  57.  
  58. CONST
  59.   MaxName = 31;
  60.  
  61. TYPE
  62.  
  63.   ModName = ARRAY MaxName + 1 OF CHAR;
  64.  
  65.   MNodePtr = POINTER TO MNode;
  66.   MNode = RECORD (L.NameNode)
  67.     key     : LONGINT;
  68.     symbols : E.LSTRPTR;
  69.     imports : L.NameList;
  70.     path    : E.LSTRPTR;
  71.   END; (* MNode *)
  72.  
  73.   MList = RECORD (L.NameList) END;
  74.  
  75. VAR
  76.   ModuleList  : L.NameList; (* List of modules discovered. *)
  77.   Dependants  : MList;  (* List of dependant modules. *)
  78.  
  79. (*------------------------------------*)
  80. PROCEDURE (VAR list : MList) Enqueue * (node : L.NodePtr);
  81.  
  82.   VAR next : L.NodePtr;
  83.  
  84. BEGIN (* Enqueue *)
  85.   WITH node : MNodePtr DO
  86.     next := list.head;
  87.     WHILE (next # NIL) & (next(MNodePtr).key <= node.key) DO
  88.       next := next.succ
  89.     END;
  90.     IF next = NIL THEN list.AddTail (node)
  91.     ELSE list.Insert (node, next.pred)
  92.     END
  93.   END;
  94. END Enqueue;
  95.  
  96. (*------------------------------------*)
  97. PROCEDURE Init ();
  98. (*
  99.  *  Simply initialises global variables.
  100.  *)
  101.  
  102. BEGIN (* Init *)
  103.   Extension := SYS.ADR (DefaultExtension);
  104.   ModuleList.NewList;
  105.   Dependants.NewList
  106. END Init;
  107.  
  108.  
  109. (*------------------------------------*)
  110. PROCEDURE GetArgs ();
  111. (*
  112.  *  Parses the command line arguments.
  113.  *)
  114.  
  115.   CONST DuplicateArg = " !! Argument duplicated\n\n";
  116.         PathMissing  = " !! <path> missing\n\n";
  117.         ModAndAll    = " !! both <module> and ALL specified\n\n";
  118.         TooManySyms  = " !! Too many symbol file search paths\n";
  119.         TooManySrcs  = " !! Too many source file search paths\n";
  120.         CmdMissing   = " !! <command> missing\n\n";
  121.         ExtMissing   = " !! <extension> missing\n\n";
  122.         WithMissing  = " !! <file> missing\n\n";
  123.         ArgTooLong   = " !! Argument in WITH file too long\n";
  124.         BadArg       = " !! Unrecognised argument in WITH file\n";
  125.  
  126.   VAR moduleFound, destFound, cmdFound, extFound : BOOLEAN; arg : INTEGER;
  127.       argStr : ARRAY 256 OF CHAR;
  128.  
  129.   (*------------------------------------*)
  130.   PROCEDURE Greeting ();
  131.  
  132.   BEGIN (* Greeting *)
  133.     Out.String (ORURev.vString);
  134.     Out.String (CopyrightStr);
  135.     Out.String (UsageStr);
  136.     Out.Ln
  137.   END Greeting;
  138.  
  139.   (*------------------------------------*)
  140.   PROCEDURE Usage ();
  141.  
  142.   BEGIN (* Usage *)
  143.     Out.String ("Usage:   ORU {option} <module>|ALL\n\n");
  144.     Out.String ("Options: NOTCD {WITH <file>}\n");
  145.     Out.String ("         {SYM | SYMBOLS <path>}\n");
  146.     Out.String ("         {SRC | SOURCE} <path>}\n");
  147.     Out.String ("         DST | DESTINATION <path>\n");
  148.     Out.String ("         EXT | EXTENSION <extension>\n\n");
  149.   END Usage;
  150.  
  151.   (*------------------------------------*)
  152.   PROCEDURE ParseWithFile (VAR fileName : ARRAY OF CHAR);
  153.  
  154.     VAR file : Files.File; r : Files.Rider; argStr : ARRAY 256 OF CHAR;
  155.  
  156.     (*------------------------------------*)
  157.     PROCEDURE BailOut (msg : ARRAY OF CHAR);
  158.  
  159.     <*$CopyArrays-*>
  160.     BEGIN (* BailOut *)
  161.       Out.String (msg); Usage (); Files.Close (file); HALT (10)
  162.     END BailOut;
  163.  
  164.     (*------------------------------------*)
  165.     PROCEDURE BailOut2 (msg : ARRAY OF CHAR);
  166.  
  167.     <*$CopyArrays-*>
  168.     BEGIN (* BailOut2 *)
  169.       Out.String (msg); Files.Close (file); HALT (10)
  170.     END BailOut2;
  171.  
  172.     (*------------------------------------*)
  173.     PROCEDURE GetNextArg ();
  174.  
  175.       VAR i : LONGINT; ch : CHAR;
  176.  
  177.     BEGIN (* GetNextArg *)
  178.       Files.Read (r, ch);
  179.       (* Skip white space *)
  180.       WHILE (ch <= " ") & ~r.eof DO Files.Read (r, ch) END;
  181.       IF r.eof THEN
  182.         RETURN
  183.       ELSIF ch = 22X THEN
  184.         (* Quoted argument *)
  185.         i := 0; Files.Read (r, ch);
  186.         WHILE (i < 255) & (ch # 22X) & ~r.eof DO
  187.           argStr [i] := ch; INC (i); Files.Read (r, ch)
  188.         END;
  189.         argStr [i] := 0X;
  190.         IF ch = 22X THEN Files.Read (r, ch)
  191.         ELSIF ~r.eof THEN BailOut2 (ArgTooLong)
  192.         END;
  193.       ELSE
  194.         i := 0;
  195.         WHILE (i < 255) & (ch > " ") & ~r.eof DO
  196.           argStr [i] := ch; INC (i); Files.Read (r, ch)
  197.         END;
  198.         argStr [i] := 0X;
  199.         IF (ch > " ") & ~r.eof THEN BailOut2 (ArgTooLong) END
  200.       END; (* ELSE *)
  201.     END GetNextArg;
  202.  
  203.     (*------------------------------------*)
  204.     PROCEDURE CopyArg () : E.LSTRPTR;
  205.  
  206.       VAR copy : E.LSTRPTR;
  207.  
  208.     BEGIN (* CopyArg *)
  209.       SYS.NEW (copy, SYS.STRLEN (argStr) + 1);
  210.       COPY (argStr, copy^);
  211.       RETURN copy
  212.     END CopyArg;
  213.  
  214.   BEGIN (* ParseWithFile *)
  215.     file := Files.Old (fileName);
  216.     IF file # NIL THEN
  217.       Files.Set (r, file, 0); GetNextArg ();
  218.       WHILE ~r.eof DO
  219.         Str.Cap (argStr);
  220.         IF argStr = "NOTCD" THEN
  221.           IF NotCD THEN BailOut (DuplicateArg) END;
  222.           NotCD := TRUE
  223.         ELSIF (argStr = "SYM") OR (argStr = "SYMBOLS") THEN
  224.           GetNextArg ();
  225.           IF r.eof THEN BailOut (PathMissing)
  226.           ELSIF NumSymbols >= MaxPaths THEN
  227.           BailOut2 (TooManySyms)
  228.           END;
  229.           Symbols [NumSymbols] := CopyArg ();
  230.           INC (NumSymbols); Symbols [NumSymbols] := NIL;
  231.         ELSIF (argStr = "SRC") OR (argStr = "SOURCE") THEN
  232.           GetNextArg ();
  233.           IF r.eof THEN BailOut (PathMissing)
  234.           ELSIF NumSources >= MaxPaths THEN BailOut2 (TooManySrcs)
  235.           END;
  236.           Source [NumSources] := CopyArg ();
  237.           INC (NumSources); Source [NumSources] := NIL;
  238.         ELSIF (argStr = "EXT") OR (argStr = "EXTENSION") THEN
  239.           GetNextArg ();
  240.           IF r.eof OR extFound THEN
  241.             IF extFound THEN BailOut (DuplicateArg)
  242.             ELSE BailOut (ExtMissing)
  243.             END;
  244.           END;
  245.           Extension := CopyArg (); extFound := TRUE
  246.         ELSE
  247.           BailOut (BadArg)
  248.         END; (* ELSE *)
  249.         GetNextArg ();
  250.       END; (* WHILE *)
  251.       Files.Set (r, NIL, 0); Files.Close (file);
  252.     ELSE
  253.       Out.String (" !! Could not open "); Out.String (fileName); Out.Ln
  254.     END; (* ELSE *)
  255.   END ParseWithFile;
  256.  
  257.   (*------------------------------------*)
  258.   PROCEDURE BailOut (msg : ARRAY OF CHAR);
  259.  
  260.   <*$CopyArrays-*>
  261.   BEGIN (* BailOut *)
  262.     Out.String (msg); Usage ();  HALT (10)
  263.   END BailOut;
  264.  
  265.   (*------------------------------------*)
  266.   PROCEDURE BailOut2 (msg : ARRAY OF CHAR);
  267.  
  268.   <*$CopyArrays-*>
  269.   BEGIN (* BailOut2 *)
  270.     Out.String (msg); HALT (10)
  271.   END BailOut2;
  272.  
  273. BEGIN (* GetArgs *)
  274.   moduleFound := FALSE; destFound := FALSE; cmdFound := FALSE;
  275.   extFound := FALSE;
  276.   IF Args.IsCLI THEN
  277.     Greeting ();
  278.     IF Args.argc < 2 THEN
  279.       (* Minimum of one argument needed *)
  280.       BailOut (" !! Arguments missing\n\n")
  281.     END;
  282.     Symbols [0] := SYS.ADR (DefaultPath);
  283.     NumSymbols := 1; Symbols [1] := NIL;
  284.     arg := 1; (* first argument is the program name, so ignore it. *)
  285.     WHILE arg < Args.argc DO
  286.       COPY (Args.argv [arg]^, argStr); Str.Cap (argStr);
  287.       IF argStr = "NOTCD" THEN
  288.         IF NotCD THEN BailOut (DuplicateArg) END;
  289.         NotCD := TRUE
  290.       ELSIF (argStr = "SYM") OR (argStr = "SYMBOLS") THEN
  291.         INC (arg);
  292.         IF arg >= Args.argc THEN BailOut (PathMissing)
  293.         ELSIF NumSymbols >= MaxPaths THEN BailOut2 (TooManySyms)
  294.         END;
  295.         Symbols [NumSymbols] := Args.argv [arg];
  296.         INC (NumSymbols); Symbols [NumSymbols] := NIL;
  297.       ELSIF (argStr = "SRC") OR (argStr = "SOURCE") THEN
  298.         INC (arg);
  299.         IF arg >= Args.argc THEN BailOut (PathMissing)
  300.         ELSIF NumSources >= MaxPaths THEN BailOut2 (TooManySrcs)
  301.         END;
  302.         Source [NumSources] := Args.argv [arg];
  303.         INC (NumSources); Source [NumSources] := NIL;
  304.       ELSIF (argStr = "DST") OR (argStr = "DESTINATION") THEN
  305.         INC (arg);
  306.         IF (arg >= Args.argc) OR destFound THEN
  307.           IF destFound THEN BailOut (DuplicateArg)
  308.           ELSE BailOut (PathMissing)
  309.           END;
  310.         END;
  311.         Destination := Args.argv [arg]; destFound := TRUE
  312.       ELSIF (argStr = "EXT") OR (argStr = "EXTENSION") THEN
  313.         INC (arg);
  314.         IF (arg >= Args.argc) OR extFound THEN
  315.           IF extFound THEN BailOut (DuplicateArg)
  316.           ELSE BailOut (ExtMissing)
  317.           END;
  318.         END;
  319.         Extension := Args.argv [arg]; extFound := TRUE
  320.       ELSIF argStr = "ALL" THEN
  321.         IF All THEN BailOut (DuplicateArg)
  322.         ELSIF moduleFound THEN BailOut (ModAndAll)
  323.         END;
  324.         Module := SYS.ADR("All"); All := TRUE
  325.       ELSIF argStr = "WITH" THEN
  326.         INC (arg);
  327.         IF arg >= Args.argc THEN BailOut (WithMissing) END;
  328.         ParseWithFile (Args.argv [arg]^)
  329.       ELSE
  330.         IF moduleFound THEN BailOut (DuplicateArg)
  331.         ELSIF All THEN BailOut (ModAndAll)
  332.         END;
  333.         Module := Args.argv [arg]; moduleFound := TRUE
  334.       END; (* ELSE *)
  335.       INC (arg)
  336.     END; (* WHILE *)
  337.     IF ~moduleFound & ~All THEN BailOut (" !! <module> missing\n\n") END;
  338.   ELSE
  339.     IU.SimpleNotice
  340.       (NIL, SYS.ADR ("Sorry, no support for Workbench yet :-("));
  341.     HALT (10)
  342.   END; (* ELSE *)
  343. END GetArgs;
  344.  
  345.  
  346. (*------------------------------------*)
  347. PROCEDURE SearchSymbolFile (directory : E.LSTRPTR; fileName : ARRAY OF CHAR);
  348.  
  349.   VAR
  350.     F : Files.File; R : Files.Rider; tag : LONGINT; modName : ModName;
  351.     module : MNodePtr; import : L.NameNodePtr;
  352.  
  353.   (*------------------------------------*)
  354.   PROCEDURE ReadModAnchor (VAR n : ARRAY OF CHAR) : BOOLEAN;
  355.  
  356.     CONST
  357.       BadName = "\x9B\x4B !! Bad name in symbol file ";
  358.  
  359.     VAR s : SHORTINT; ch : CHAR; key : LONGINT;
  360.  
  361.   BEGIN (* ReadModAnchor *)
  362.     Files.Read (R, s); (* modAnchor *)
  363.     IF s = eMod THEN
  364.       Files.ReadBytes (R, key, 4); s := 0;
  365.       LOOP
  366.         Files.Read (R, ch); n [s] := ch;
  367.         IF ch = 0X THEN EXIT END;
  368.         INC (s);
  369.         IF s > MaxName THEN
  370.           n [MaxName] := 0X;
  371.           Out.String (BadName); Out.String (fileName); Out.Ln;
  372.           WHILE ch # 0X DO Files.Read (R, ch) END;
  373.           RETURN FALSE
  374.         END; (* IF *)
  375.       END; (* LOOP *)
  376.       RETURN TRUE
  377.     END; (* IF *)
  378.     RETURN FALSE
  379.   END ReadModAnchor;
  380.  
  381. <*$CopyArrays-*>
  382. BEGIN (* SearchSymbolFile *)
  383.   Out.String ("\x9B\x4B << "); Out.String (fileName); Out.Char (0DX);
  384.   F := Files.Old (fileName);
  385.   IF F = NIL THEN Out.String (OpenError); Out.String (fileName); Out.Ln;
  386.   ELSE
  387.     Files.Set (R, F, 0); Files.ReadBytes (R, tag, 4);
  388.     IF tag # SymFileTag THEN
  389.       Out.String ("\x9B\x4B !! "); Out.String (fileName);
  390.       Out.String (" is obsolete, or is not a symbol file"); Out.Ln
  391.     ELSE
  392.       IF ReadModAnchor (modName) THEN
  393.         NEW (module);
  394.         module.Name (modName); module.key := 0;
  395.         module.symbols := directory; module.imports.NewList;
  396.         ModuleList.AddTail (module);
  397.         WHILE ReadModAnchor (modName) DO
  398.           NEW (import); import.Name (modName);
  399.           module.imports.AddTail (import);
  400.         END;
  401.       END;
  402.     END;
  403.     Files.Set (R, NIL, 0); Files.Close (F)
  404.   END;
  405. END SearchSymbolFile;
  406.  
  407.  
  408. (*------------------------------------*)
  409. PROCEDURE ScanForSymbols (directory : E.LSTRPTR);
  410.  
  411.   CONST
  412.     LockError    = " !! Failed to lock ";
  413.  
  414.   VAR
  415.     lock, oldLock : D.FileLockPtr;
  416.     myAnchor : D.AnchorPathPtr;
  417.     result : LONGINT;
  418.  
  419. BEGIN (* ScanForSymbols *)
  420.   IF directory = NIL THEN directory := SYS.ADR ("") END;
  421.   lock := D.Lock (directory^, D.sharedLock);
  422.   IF lock = NIL THEN
  423.     Out.String (LockError); Out.String (directory^); Out.Ln; RETURN
  424.   END;
  425.  
  426.   oldLock := D.CurrentDir (lock);
  427.  
  428.   NEW (myAnchor); myAnchor.strlen := SHORT (LEN (myAnchor.buf));
  429.   result := D.MatchFirst ("#?.sym", myAnchor^);
  430.   WHILE result = 0 DO
  431.     SearchSymbolFile (directory, myAnchor.buf);
  432.     result := D.MatchNext (myAnchor^)
  433.   END;
  434.   D.MatchEnd (myAnchor^);
  435.  
  436.   oldLock := D.CurrentDir (oldLock);
  437.   D.UnLock (lock)
  438. END ScanForSymbols;
  439.  
  440.  
  441. (*------------------------------------*)
  442. PROCEDURE SearchForDependants (modName : ARRAY OF CHAR; level : LONGINT);
  443.  
  444.   VAR node, module, import : L.NodePtr;
  445.  
  446. <*$CopyArrays-*>
  447. BEGIN (* SearchForDependants *)
  448.   module := ModuleList.FindCap (modName);
  449.   IF module = NIL THEN
  450.     Out.String (" !! Module "); Out.String (modName);
  451.     Out.String (" not found\n"); Out.Ln
  452.   ELSE
  453.     IF module(MNodePtr).key < level THEN
  454.       module(MNodePtr).key := level;
  455.       node := ModuleList.head;
  456.       WHILE node # NIL DO
  457.         WITH node : MNodePtr DO
  458.           import := node.imports.FindCap (modName);
  459.           IF import # NIL THEN
  460.             SearchForDependants (node.name^, level + 1)
  461.           END;
  462.         END;
  463.         node := node.succ
  464.       END;
  465.     END;
  466.   END;
  467. END SearchForDependants;
  468.  
  469.  
  470. (*------------------------------------*)
  471. PROCEDURE SearchForAll ();
  472.  
  473.   VAR node, module, import : L.NodePtr;
  474.  
  475. BEGIN (* SearchForAll *)
  476.   module := ModuleList.head;
  477.   WHILE module # NIL DO
  478.     IF module(MNodePtr).key = 0 THEN
  479.       module(MNodePtr).key := 1;
  480.       node := ModuleList.head;
  481.       WHILE node # NIL DO
  482.         WITH node : MNodePtr DO
  483.           import := node.imports.Find (module(L.NameNodePtr).name^);
  484.           IF import # NIL THEN
  485.             SearchForDependants (node.name^, 2)
  486.           END;
  487.         END; (* WITH node *)
  488.         node := node.succ
  489.       END; (* WHILE *)
  490.     END;
  491.     module := module.succ;
  492.   END; (* WHILE *)
  493. END SearchForAll;
  494.  
  495.  
  496. (*------------------------------------*)
  497. PROCEDURE SortDependants ();
  498.  
  499.   VAR node : L.NodePtr;
  500.  
  501. BEGIN (* SortDependants *)
  502.   LOOP
  503.     node := ModuleList.RemHead ();
  504.     IF node = NIL THEN EXIT END;
  505.     WITH node : MNodePtr DO
  506.       IF node.key > 0 THEN Dependants.Enqueue (node) END
  507.     END; (* WITH *)
  508.   END; (* LOOP *)
  509. END SortDependants;
  510.  
  511.  
  512. (*------------------------------------*)
  513. PROCEDURE FileExists (path : ARRAY OF CHAR) : BOOLEAN;
  514.  
  515.   VAR lock : D.FileLockPtr; result : BOOLEAN;
  516.  
  517. <*$CopyArrays-*>
  518. BEGIN (* FileExists *)
  519.   result := FALSE;
  520.   lock := D.Lock (path, D.sharedLock);
  521.   IF lock # NIL THEN result := TRUE; D.UnLock (lock) END;
  522.   RETURN result
  523. END FileExists;
  524.  
  525. (*------------------------------------*)
  526. PROCEDURE Search (file : ARRAY OF CHAR; VAR path : E.LSTRPTR) : BOOLEAN;
  527.  
  528.   VAR
  529.     index : INTEGER; fullPath : ARRAY 256 OF CHAR;
  530.     len : LONGINT; ch : CHAR;
  531.  
  532. <*$CopyArrays-*>
  533. BEGIN (* Search *)
  534.   path := NIL;
  535.   IF NotCD THEN
  536.     IF Source [0] = NIL THEN RETURN FALSE END;
  537.     COPY (Source [0]^, fullPath); index := 0
  538.   ELSE
  539.     fullPath [0] := 0X; index := -1
  540.   END;
  541.   LOOP
  542.     len := Str.Length (fullPath);
  543.     IF len > 0 THEN
  544.       ch := fullPath [len - 1];
  545.       IF (ch # "/") & (ch # ":") THEN Str.Append ("/", fullPath) END
  546.     END;
  547.     Str.Append (file, fullPath); Str.Append (Extension^, fullPath);
  548.     IF FileExists (fullPath) THEN
  549.       IF index >= 0 THEN path := Source [index] END;
  550.       RETURN TRUE
  551.     END;
  552.     INC (index);
  553.     IF Source [index] = NIL THEN RETURN FALSE
  554.     ELSE COPY (Source [index]^, fullPath)
  555.     END
  556.   END
  557. END Search;
  558.  
  559. (*------------------------------------*)
  560. PROCEDURE SearchForSources ();
  561.  
  562.   VAR node, succ : L.NodePtr;
  563.  
  564. BEGIN (* SearchForSources *)
  565.   node := Dependants.head;
  566.   WHILE node # NIL DO
  567.     succ := node.succ;
  568.     WITH node : MNodePtr DO
  569.       IF ~Search (node.name^, node.path) THEN
  570.         Dependants.Remove (node)
  571.       END
  572.     END;
  573.     node := succ
  574.   END;
  575. END SearchForSources;
  576.  
  577.  
  578. (*------------------------------------*)
  579. PROCEDURE OutputModules (batchFile : ARRAY OF CHAR);
  580.  
  581.   VAR
  582.     F : Files.File; R : Files.Rider; module : L.NodePtr;
  583.     len : LONGINT; ch : CHAR;
  584.  
  585. <*$CopyArrays-*>
  586. BEGIN (* OutputModules *)
  587.   F := Files.New (batchFile);
  588.   IF F = NIL THEN
  589.     Out.String (OpenError); Out.String (batchFile); Out.Ln
  590.   ELSE
  591.     Files.Set (R, F, 0);
  592.     module := Dependants.head;
  593.     WHILE module # NIL DO
  594.       WITH module : MNodePtr DO
  595.         IF module.path # NIL THEN
  596.           len := Str.Length (module.path^);
  597.           IF len > 0 THEN
  598.             Files.WriteBytes (R, module.path^, len);
  599.             ch := module.path^ [len - 1];
  600.             IF (ch # "/") & (ch # ":") THEN Files.Write (R, "/") END;
  601.           END
  602.         END;
  603.         Files.WriteBytes (R, module.name^, Str.Length (module.name^));
  604.       END;
  605.       Files.WriteBytes (R, Extension^, Str.Length (Extension^));
  606.       Files.Write (R, "\n");
  607.       module := module.succ
  608.     END;
  609.     Files.Set (R, NIL, 0); Files.Register (F)
  610.   END;
  611. END OutputModules;
  612.  
  613.  
  614. (*------------------------------------*)
  615. PROCEDURE Main ();
  616. (*
  617.  *  The main body of the program.
  618.  *
  619.  *  The basic sequence is:
  620.  *
  621.  *    * Scan the current directory and the Symbols list.  With each symbol
  622.  *      file found:
  623.  *        * Add the module to the list of modules found.
  624.  *        * Open the symbol file and create a list of the modules it
  625.  *          imports.
  626.  *    * Search the module list for modules that import the redefined module
  627.  *      and add them to a list of dependant modules.
  628.  *    * Search the current directory and the Sources list for the source
  629.  *      files of the dependant modules.
  630.  *    * Output the list to the script file using the command template.
  631.  *)
  632.  
  633.   VAR index : INTEGER; batchFile : ARRAY 256 OF CHAR;
  634.     len : LONGINT; ch : CHAR;
  635.  
  636. BEGIN (* Main *)
  637.   Out.String (" !! Scanning for symbol files\n");
  638.   IF ~NotCD THEN
  639.     Out.String ("    Scanning current directory\n"); ScanForSymbols (NIL)
  640.   END;
  641.  
  642.   index := 0;
  643.   WHILE Symbols [index] # NIL DO
  644.     Out.String ("\x9B\x4B    Scanning "); Out.String (Symbols [index]^);
  645.     Out.Ln;
  646.     ScanForSymbols (Symbols [index]); INC (index)
  647.   END;
  648.  
  649.   IF All THEN
  650.     Out.String ("\x9B\x4B !! Searching for all dependant modules"); Out.Ln;
  651.     SearchForAll ()
  652.   ELSE
  653.     Out.String ("\x9B\x4B !! Searching for dependants of ");
  654.     Out.String (Module^); Out.Ln;
  655.     SearchForDependants (Module^, 1);
  656.   END; (* ELSE *)
  657.  
  658.   Out.String ("\x9B\x4B !! Sorting dependant modules\n");
  659.   SortDependants ();
  660.  
  661.   Out.String ("\x9B\x4B !! Searching for source files\n");
  662.   SearchForSources ();
  663.  
  664.   IF Destination = NIL THEN
  665.     batchFile := ""
  666.   ELSE
  667.     COPY (Destination^, batchFile); len := Str.Length (batchFile);
  668.     IF len > 0 THEN
  669.       ch := batchFile [len - 1];
  670.       IF (ch # "/") & (ch # ":") THEN Str.Append ("/", batchFile) END
  671.     END
  672.   END;
  673.   Str.Append (Module^, batchFile); Str.Append (".bat", batchFile);
  674.   Out.String ("\x9B\x4B !! Creating batch file "); Out.String (batchFile);
  675.   Out.Ln;
  676.   OutputModules (batchFile)
  677. END Main;
  678.  
  679.  
  680. BEGIN (* ORU *)
  681.   Errors.Init;
  682.   Init ();
  683.   GetArgs ();
  684.   Main ();
  685. END ORU.
  686.  
  687. (***************************************************************************
  688.  
  689.   $Log: ORU.mod $
  690.   Revision 2.8  1995/01/26  02:13:59  fjc
  691.   - Release 1.5
  692.  
  693.   Revision 2.7  1994/09/25  18:30:40  fjc
  694.   - Uses new syntax for external code declarations
  695.  
  696.   Revision 2.6  1994/09/03  16:32:01  fjc
  697.   - Gets version string from ORURev.
  698.  
  699.   Revision 2.5  1994/08/08  16:38:47  fjc
  700.   Release 1.4
  701.  
  702.   Revision 2.4  1994/06/17  18:09:17  fjc
  703.   - Updated for release
  704.  
  705.   Revision 2.3  1994/06/05  00:11:07  fjc
  706.   - Updated symbol file tag to new version
  707.   - Changed to use new Amiga interface
  708.  
  709.   Revision 2.2  1994/05/21  22:47:40  fjc
  710.   - Removed case-sensitivity of module parameter
  711.   - Appends "/" to paths not ending in "/" or ":"
  712.  
  713.   Revision 2.1  1994/05/19  23:23:19  fjc
  714.   - Bumped version number.
  715.   - Changed to generate a batch file to be used with the BATCH
  716.     option of the compiler.
  717.   - OLIB: is now the default symbol file search path.
  718.  
  719.   Revision 1.3  1994/05/11  23:40:54  fjc
  720.   - Added copyright notice to file header
  721.   - Changed greeting
  722.  
  723.   Revision 1.2  1994/01/25  10:07:37  fjc
  724.   - Updated greeting
  725.  
  726.   Revision 1.1  1994/01/15  19:02:30  fjc
  727.   - Start of revision control
  728.  
  729.   0.4  (02-Jan-94)  Recognises new symbol file tags.
  730.   0.3  (28-Dec-93)  Increased MaxPaths.
  731.   0.2  (30-Sep-93)  Add ALL and WITH options.
  732.   0.1  (06-Sep-93)  First public release.
  733.   0.0  (27-Aug-93)  Initial version.
  734.  
  735. ***************************************************************************)
  736.  
  737.  
  738.